package zsl.algo;

import java.util.ArrayList;
import java.util.Vector;

import zsl.utils.WordCount;
import zsl.utils.WordCountList;

public class YetATA {
	
	public static ArrayList<WordCount> getTopK(int k, Vector<WordCountList> lists, StringBuffer sb){
		int threashold = 0;
		ArrayList<WordCount> topK = new ArrayList<>(k);
	
		int maxDepth = getMaxDepth(lists);
		WordCount wc;
		WordCount overAllwc;
		for (int i = 0; i < maxDepth; i++) {
			threashold = 0;
			for (WordCountList list : lists) {
				if (i<list.size()) {
					wc = list.get(i);
					threashold += wc.getCount();
					if(!isTopk(wc, topK)){
						overAllwc = getOverAllCount(wc, lists);
						detectAndAddToTopK(overAllwc, topK, k);
					}
				}
			}
			if (topK.size() == k && topK.get(k-1).getCount() >= threashold) {
				if (sb != null) {
					sb.append("In TA, depth = " + maxDepth + ", access depth = " + i +", access percent is " + ((double)i)/((double)maxDepth)+"\n");
				}
				break;
			}
		}
		System.out.println(topK);
		return topK;
		
	}
	
	private static boolean isTopk(WordCount wc, ArrayList<WordCount> topK){
		
		for(WordCount tempWC : topK){
			if(wc.getWord().equals(tempWC.getWord())){
				return true;
			}
		}
		
		return false;
	}
	
	private static int getMaxDepth(Vector<WordCountList> lists){
		int curMaxDepth = lists.get(0).size();
		for (WordCountList wordCountList : lists) {
			if (wordCountList.size()>curMaxDepth) {
				curMaxDepth = wordCountList.size();
			}
		}
		return curMaxDepth;
	}
		
	private static void detectAndAddToTopK(WordCount wc, ArrayList<WordCount> topK, int k) {
		int size = topK.size();
		
		if (size == k && topK.get(size-1).getCount() >= wc.getCount()) {
			return ;
		}
		
		for (int i = 0; i < size; i++) {
			
			if (topK.get(i).getCount() < wc.getCount()) {
				topK.add(i, wc);
				if (topK.size() > k) {
					topK.remove(topK.size()-1);
				}
				return ;
			}
			
		}
		
		topK.add(wc);

		if (topK.size() > k) {
			topK.remove(topK.size()-1);
		}
	}
	
	private static WordCount getOverAllCount(WordCount wc, Vector<WordCountList> lists){
		int overAllCount = 0;
		for (WordCountList wordCountList : lists) {
			overAllCount += wordCountList.getCount(wc.getWord());
		}
		
		return new WordCount(wc.getWord(), overAllCount);
	}
	

}
